import tokenConfig from '@/config/modules/cache';
import { encrypt } from '@/config/modules/network';
const { tokenName } = tokenConfig;
import { setObjToUrlParams, objToUrlParams } from '@/utils';
import { isString } from '@/utils/is';
import { getToken } from '@/utils/token';
import { joinTimestamp, formatRequestDate } from './helpers';
import { checkStatus, checkInvalidStatus } from './checkStatus';
import { AxiosCanceler } from './axiosCancel';
import smCrypto from '@/utils/smCrypto';

const axiosCanceler = new AxiosCanceler();

export function reqResolve(config) {
	const { ignoreCancelToken, formatDate, joinTime = true, joinParamsToUrl } = config.requestOptions;
	// 如果启用了取消重复请求，则禁止取消重复请求
	const ignoreCancel = ignoreCancelToken !== undefined ? ignoreCancelToken : true;
	!ignoreCancel && axiosCanceler.addPending(config);

	// 防止缓存，给get请求加上时间戳
	const params = config.params || {};
	const data = config.data || false;
	formatDate && data && !isString(data) && formatRequestDate(data);
	if (config.method?.toUpperCase() === 'GET') {
		if (!isString(params)) {
			// 给 get 请求加上时间戳参数，避免从缓存中拿数据。
			config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
		} else {
			// 兼容restful风格
			config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
			config.params = undefined;
		}
	} else {
		if (!isString(params)) {
			formatDate && formatRequestDate(params);
			if (Reflect.has(config, 'data') && config.data && (Object.keys(config.data).length > 0 || config.data instanceof FormData)) {
				config.data = data;
				config.params = params;
			} else {
				// 非GET请求如果没有提供data，则将params视为data
				config.data = params;
				config.params = undefined;
			}
			if (joinParamsToUrl) {
				config.url = setObjToUrlParams(config.url, Object.assign({}, config.params, config.data));
			}
		} else {
			// 兼容restful风格
			config.url = config.url + params;
			config.params = undefined;
		}
	}
	if (config.headers['content-Type'] === 'application/x-www-form-urlencoded;charset=UTF-8') {
		if (config.data) {
			//  将 object 转成 字符串
			config.data = objToUrlParams(config.data);
		}
	}
	const token = getToken();
	if (token) {
		config.headers[tokenName] = token;
	}
	return config;
}

export function reqReject(error) {
	return Promise.reject(error);
}

export function resResolve(response) {
	response && axiosCanceler.removePending(response.config);
	const data = response?.data;
	if (data && data?.code !== 200) {
		return checkInvalidStatus(data);
	} else {
		if (encrypt && data?.data) {
			data.data = decrypt(data.data);
		}
		return data;
	}
}

export function resReject(error) {
	return checkStatus(error);
}

function decrypt(data) {
	if (data) {
		try {
			const decryptDate = smCrypto.doSm2Decrypt(data);
			return JSON.parse(decryptDate)['wangbuhao'];
		} catch (error) {
			console.error('解密失败');
			return data;
		}
	} else {
		return data;
	}
}
